﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.Text;
using System.Web;
using System.IO;
using InfoJetSoft.Service.Entity;
using InfoJetSoft.Service.Util;

namespace InfoJetSoft.Service.Worker
{
	
	class XSNManifestParseWorker
	{
		public static void  parseSolutionFormatVersion(Manifest manifest)
		{
			XmlElement root = manifest.Doc.DocumentElement;
			string solutionFormatVersionValue = root.GetAttribute("solutionFormatVersion");
			if (solutionFormatVersionValue == null || solutionFormatVersionValue.Length <= 0)
			{
				throw new InfoJetException("No solutionFormatVersion.", "XMP08");
			}
			/*
			if (solutionFormatVersionValue.Equals(JetConstant.VER_2003) || solutionFormatVersionValue.Equals(JetConstant.VER_2003SP1))
			{
				manifest.SolutionFormatVersion = solutionFormatVersionValue;
			}
			else
			{
				throw new InfoJetException("Not support solutionFormatVersion: " + solutionFormatVersionValue, "XMP08");
			}
			*/
			manifest.SolutionFormatVersion = solutionFormatVersionValue;
		}
		
		public static void  parseSolutionVersion(Manifest manifest)
		{
			XmlElement root = manifest.Doc.DocumentElement;
			string solutionVersionValue = root.GetAttribute("solutionVersion");
			manifest.SolutionVersion = new VersionCode( solutionVersionValue );
		}

		public static void  parseProductVersion(Manifest manifest)
		{
			XmlElement root = manifest.Doc.DocumentElement;
			string productVersionValue = root.GetAttribute("productVersion");
			if( productVersionValue == null || productVersionValue.Length <= 0 )
			{
				manifest.ProductVersion = new VersionCode( 11, 0, 6357, 0 );
			}
			else
			{
				manifest.ProductVersion = new VersionCode( productVersionValue );
			}
		}

        //CID 0703 //2010.12.20 //Begin
        public static void parseRelativeUrlBase(Manifest manifest)
        {
            XmlElement root = manifest.Doc.DocumentElement;
            string xsfPrefix = manifest.XsfPrefix;
            string xsf3Prefix = manifest.Xsf3Prefix;

            if (xsf3Prefix != null)
            {
                StringBuilder schemaFilterBuffer = new StringBuilder();
                schemaFilterBuffer.Append("/");
                schemaFilterBuffer.Append(NamespaceUtil.toFullName(xsfPrefix, "xDocumentClass"));
                schemaFilterBuffer.Append("/");
                schemaFilterBuffer.Append(NamespaceUtil.toFullName(xsfPrefix, "extensions"));
                schemaFilterBuffer.Append("/");
                schemaFilterBuffer.Append(NamespaceUtil.toFullName(xsfPrefix, "extension"));
                schemaFilterBuffer.Append("/");
                schemaFilterBuffer.Append(NamespaceUtil.toFullName(xsf3Prefix, "solutionDefinition"));
                schemaFilterBuffer.Append("/");
                schemaFilterBuffer.Append(NamespaceUtil.toFullName(xsf3Prefix, "baseUrl"));

                XmlElement baseUrlElement = DOMUtil.selectANode(root, schemaFilterBuffer.ToString(), manifest.NsResolver) as XmlElement;
                if (baseUrlElement != null)
                {
                    manifest.RelativeUrlBase = baseUrlElement.GetAttribute("relativeUrlBase");
                }
            }
        }
        //CID 0703 //2010.12.20 //End
		
		public static void parseSchemaDefs(Manifest manifest)
		{
			XmlElement root = manifest.Doc.DocumentElement;
			string xsfPrefix = manifest.XsfPrefix;
			
			StringBuilder schemaFilterBuffer = new StringBuilder();
            schemaFilterBuffer.Append("/");
            schemaFilterBuffer.Append(NamespaceUtil.toFullName(xsfPrefix, "xDocumentClass"));
            schemaFilterBuffer.Append("/");
			schemaFilterBuffer.Append(NamespaceUtil.toFullName(xsfPrefix, "documentSchemas"));
			schemaFilterBuffer.Append("/");
			schemaFilterBuffer.Append(NamespaceUtil.toFullName(xsfPrefix, "documentSchema"));
			
			XmlNodeList documentSchemaList = DOMUtil.selectNodes(root, schemaFilterBuffer.ToString(), 0, manifest.NsResolver);
			if (documentSchemaList.Count <= 0)
			{
				//throw new InfoJetException("must have schema", "XMP04");
			}
			
			ArrayList schemaList = new ArrayList();
			foreach ( XmlNode schemaNode in documentSchemaList )
			{
				XmlElement documentSchema = (XmlElement) schemaNode;
				string isRootSchema = documentSchema.GetAttribute("rootSchema");
				if (isRootSchema.Equals("yes"))
				{
					SchemaDef rootSchema = parseSchemaDef(documentSchema);
					manifest.RootSchemaDef = rootSchema;
				}
				else
				{
					SchemaDef schema = parseSchemaDef(documentSchema);
					schemaList.Add(schema);
				}
			}
			if (schemaList.Count <= 0 && manifest.RootSchemaDef == null)
			{
				//throw new InfoJetException(manifest.Uri + " no schema", "XMP05");
			}
			manifest.SchemaDefList = schemaList;
			if (manifest.RootSchemaDef == null)
			{
				manifest.RootSchemaDef = (SchemaDef) schemaList[ schemaList.Count - 1 ];
			}
			manifest.RootSchemaDef.CabFile = CABFileFinder.findCABFile(manifest, manifest.RootSchemaDef.Location);
			foreach(SchemaDef schemaDef in manifest.SchemaDefList)
			{
				schemaDef.CabFile = CABFileFinder.findCABFile(manifest, schemaDef.Location);
			}
			manifest.SchemaDefList.Remove( manifest.RootSchemaDef );
		}
		
		private static SchemaDef parseSchemaDef(XmlElement documentSchema)
		{
			//2008.07.27 //Begin
			//这里location="http://schemas.microsoft.com/office/infopath/2003/myXSD/2008-07-27T14:42:22 myschema.xsd"
			//不知道什么原因,前面的Namespace被过滤掉了,得到始终是myschema.xsd. 
			//2008.07.27 //End
			string location = documentSchema.GetAttribute("location");
			if (location.Length <= 0)
			{
				throw new InfoJetException("schema no location", "XMP02");
			}
			SchemaDef schemaDef = new SchemaDef();
			StringTokenizer locationTokenizer = new StringTokenizer(location.Trim(), " ");
			ArrayList locationList = new ArrayList();
			while( locationTokenizer.HasMoreTokens() ){
				string token = locationTokenizer.NextToken();
				token = token.Trim();
				if( token.Length > 0 ){
					locationList.Add( token );
				}
			}
			if (locationList.Count == 1)
			{
				schemaDef.Uri = "";
				schemaDef.Location = (string)locationList[ 0 ];
			}
			else if (locationList.Count == 2)
			{
				schemaDef.Uri = (string)locationList[ 0 ];
				schemaDef.Location = (string)locationList[ 1 ];
			}
			else
			{
				throw new InfoJetException("location format error", "XMP03");
			}
			return schemaDef;
		}

		public static void parseTaskPanes(Manifest manifest)
		{
			XmlElement root = manifest.Doc.DocumentElement;
			string xsfPrefix = manifest.XsfPrefix;
			
			string taskpaneFilter = "//" + NamespaceUtil.toFullName(xsfPrefix, "taskpane");
			XmlNodeList taskpaneElementList = DOMUtil.selectNodes(root, taskpaneFilter, 0, manifest.NsResolver);
			foreach( XmlElement taskpaneElement in taskpaneElementList )
			{
				string caption = taskpaneElement.GetAttribute( "caption" );
				string href = taskpaneElement.GetAttribute( "href" );
				TaskPane taskPane = new TaskPane();
				taskPane.Caption = caption;
				taskPane.Href = href;
                //CID 0932 //2011.05.29 //Begin
                if (taskPane.Href.StartsWith("x-soln:///"))
                {
                    taskPane.Href = taskPane.Href.Substring(10, taskPane.Href.Length - 10);
                }
                //CID 0932 //2011.05.29 //End
				if( manifest.TaskPaneList == null )
				{
					manifest.TaskPaneList = new ArrayList();
				}
				manifest.TaskPaneList.Add( taskPane );
			}
		}

        //CID 0951 //2011.06.17 //Begin
        public static void parseSampleDataFile(Manifest manifest)
        {
            string xsfPrefix = manifest.XsfPrefix;
            XmlElement root = manifest.Doc.DocumentElement;

            StringBuilder filter = new StringBuilder();
            filter.Append("/");
            filter.Append(NamespaceUtil.toFullName(xsfPrefix, "xDocumentClass"));
            filter.Append("/");
            filter.Append(NamespaceUtil.toFullName(xsfPrefix, "package"));
            filter.Append("/");
            filter.Append(NamespaceUtil.toFullName(xsfPrefix, "files"));
            filter.Append("/");
            filter.Append(NamespaceUtil.toFullName(xsfPrefix, "file"));
            filter.Append("/");
            filter.Append(NamespaceUtil.toFullName(xsfPrefix, "fileProperties"));
            filter.Append("/");
            filter.Append(NamespaceUtil.toFullName(xsfPrefix, "property"));

            string sampleFilter = filter.ToString() + "[@value='sampleData']";

            XmlElement samplePropElement = (XmlElement)DOMUtil.selectANode(root, sampleFilter, manifest.NsResolver);
            if (samplePropElement != null)
            {
                XmlElement fileElement = samplePropElement.ParentNode.ParentNode as XmlElement;
                string name = fileElement.GetAttribute("name");
                if (name.Length > 0)
                {
                    manifest.SampleDataFile = name;
                }
            }
            if (manifest.SampleDataFile == null)
            {
                manifest.SampleDataFile = "sampledata.xml";
            }
        }
        //CID 0951 //2011.06.17 //End
		
		public static void parseViews(Manifest manifest)
		{
			XmlElement root = manifest.Doc.DocumentElement;
			string xsfPrefix = manifest.XsfPrefix;
			
			string viewsFilter = "//" + NamespaceUtil.toFullName(xsfPrefix, "views");
			XmlElement viewsElement = (XmlElement) DOMUtil.selectOneNode(root, viewsFilter, manifest.NsResolver);
			string defaultViewName = viewsElement.GetAttribute("default");
			
			string viewFilter = NamespaceUtil.toFullName(xsfPrefix, "view");
			XmlNodeList viewElementList = DOMUtil.selectNodes(viewsElement, viewFilter, 1, manifest.NsResolver);
			ArrayList viewList = new ArrayList();
			for (int i = 0; i < viewElementList.Count; i ++ ) 
			{
				XmlElement viewElement = (XmlElement) viewElementList[ i ];
				View view = new View();
				view.Manifest = manifest;
				view.Name = viewElement.GetAttribute("name");
				view.Caption = viewElement.GetAttribute("caption");
				view.PrintView = viewElement.GetAttribute("printView");
				string showMenuItem = viewElement.GetAttribute("showMenuItem");
				if( showMenuItem.Equals( "yes" ) ){
					view.ShowMenuItem = true;
				}else{
					view.ShowMenuItem = false;
				}
				view.Id = i + "";
				string mainpaneFilter = NamespaceUtil.toFullName(xsfPrefix, "mainpane");
				XmlElement mainPaneElement = (XmlElement) DOMUtil.selectOneNode(viewElement, mainpaneFilter, manifest.NsResolver);
				view.Transform = mainPaneElement.GetAttribute("transform");
                //CID 1503 //2012.12.19 //Begin
                parseViewReadonly(manifest, view);
                parseViewSignatureLines(manifest, view);
                //CID 1503 //2012.12.19 //End
				parseViewWidth( manifest, view );
				parsePrintSetting( manifest, view, viewElement );
				parseRuleButtonList( manifest, view, viewElement );
				viewList.Add(view);
				if (view.Name.Equals(defaultViewName))
				{
					manifest.DefaultView = view;
				}
			}
			manifest.ViewList = viewList;

			//判断视图是否是打印视图.
			foreach( View view in manifest.ViewList )
			{
				foreach( View curView in manifest.ViewList )
				{
					if( curView.PrintView != null && curView.PrintView.Equals( view.Name ) )
					{
						view.IsPrintView = true;
						continue;
					}
				}
			}

            //CID 1503 //2012.12.19 //Begin
            manifest.ViewExtension2List = null;
            manifest.ViewExtension3List = null;
            //CID 1503 //2012.12.19 //End
		}

        //CID 1503 //2012.12.19 //Begin
		private static void parseViewReadonly( Manifest manifest, View view )
		{
			XmlElement root = manifest.Doc.DocumentElement;
            if (manifest.ViewExtension2List == null)
            {
                XmlElement extensionsElement = DOMUtil.selectANode(root, NamespaceUtil.toFullName(manifest.XsfPrefix, "extensions"), manifest.NsResolver) as XmlElement;
                if (extensionsElement != null)
                {
                    XmlNodeList viewExtensionList = DOMUtil.selectNodes(extensionsElement, ".//" + NamespaceUtil.toFullName(manifest.Xsf2Prefix, "viewExtension"), 0, manifest.NsResolver);
                    manifest.ViewExtension2List = viewExtensionList;
                }
            }
            foreach (XmlElement viewExtensionElement in manifest.ViewExtension2List)
			{
				string refView = viewExtensionElement.GetAttribute( "ref" );
				if( refView.Equals( view.Name ) )
				{
					string viewReadonly = viewExtensionElement.GetAttribute( "readOnly" );
					if( viewReadonly.ToLower().Equals( "yes" ) )
					{
						view.IsReadonly = true;
						return;
					}
				}
			}
		}
        //CID 1503 //2012.12.19 //End

        //CID 1503 //2012.12.19 //Begin
        private static void parseViewSignatureLines(Manifest manifest, View view)
        {
            XmlElement root = manifest.Doc.DocumentElement;
            if (manifest.ViewExtension3List == null)
            {
                XmlElement extensionsElement = DOMUtil.selectANode(root, NamespaceUtil.toFullName(manifest.XsfPrefix, "extensions"), manifest.NsResolver) as XmlElement;
                if (extensionsElement != null)
                {
                    XmlNodeList viewExtensionList = DOMUtil.selectNodes(extensionsElement, ".//" + NamespaceUtil.toFullName(manifest.Xsf3Prefix, "viewExtension"), 0, manifest.NsResolver);
                    manifest.ViewExtension3List = viewExtensionList;
                }
            }
            string path = NamespaceUtil.toFullName(manifest.Xsf3Prefix, "signatureLines") + "/" + NamespaceUtil.toFullName(manifest.Xsf3Prefix, "signatureLine");
            foreach (XmlElement viewExtensionElement in manifest.ViewExtension3List)
            {
                string refView = viewExtensionElement.GetAttribute("ref");
                if (refView.Equals(view.Name))
                {
                    XmlNodeList signatureLineElementList = DOMUtil.selectNodes(viewExtensionElement, path, 0, manifest.NsResolver);
                    foreach (XmlElement signatureLineElement in signatureLineElementList)
                    {
                        SignatureLine signatureLine = new SignatureLine();
                        signatureLine.Name = signatureLineElement.GetAttribute("name");
                        signatureLine.SignedDataBlock = signatureLineElement.GetAttribute("signedDataBlock");
                        if (view.SignatureLines == null)
                        {
                            view.SignatureLines = new List<SignatureLine>();
                        }
                        view.SignatureLines.Add(signatureLine);
                    }
                }
            }
        }
        //CID 1503 //2012.12.19 //End

		private static void parsePrintSetting( Manifest manifest, View view, XmlElement viewElement )
		{
			string xsfPrefix = manifest.XsfPrefix;
			string headerFilter = NamespaceUtil.toFullName( xsfPrefix, "printSettings" ) + "/" + NamespaceUtil.toFullName( xsfPrefix, "header" ) + "/font/div";
			XmlElement headerElement = (XmlElement)DOMUtil.selectANode( viewElement, headerFilter, manifest.NsResolver );
			if( headerElement != null )
			{
				view.PrintHeader = headerElement.InnerText;
			}
			string footerFilter = NamespaceUtil.toFullName( xsfPrefix, "printSettings" ) + "/" + NamespaceUtil.toFullName( xsfPrefix, "footer" ) + "/font/div";
			XmlElement footerElement = (XmlElement)DOMUtil.selectANode( viewElement, footerFilter, manifest.NsResolver );
			if( footerElement != null )
			{
				view.PrintFooter = footerElement.InnerText;
			}
			string printSettingFilter = NamespaceUtil.toFullName( xsfPrefix, "printSettings" );
			XmlElement printSettingElement = (XmlElement)DOMUtil.selectANode( viewElement, printSettingFilter, manifest.NsResolver );
			if( printSettingElement != null )
			{
				string orientation = printSettingElement.GetAttribute( "orientation" );
				if( orientation.Equals( "landscape" ) )
				{
					view.Portrait = false;
				}
				string topMargin = printSettingElement.GetAttribute( "topMargin" );
				if( topMargin.Length > 0 )
				{
					view.TopMargin = ConvertUtil.parseDoubleWithLocalDecimalSeparator( topMargin ) * 10;
				}
				string leftMargin = printSettingElement.GetAttribute( "leftMargin" );
				if( leftMargin.Length > 0 )
				{
					view.LeftMargin = ConvertUtil.parseDoubleWithLocalDecimalSeparator( leftMargin ) * 10;
				}
				string bottomMargin = printSettingElement.GetAttribute( "bottomMargin" );
				if( bottomMargin.Length > 0 )
				{
					view.BottomMargin = ConvertUtil.parseDoubleWithLocalDecimalSeparator( bottomMargin ) * 10;
				}
				string rightMargin = printSettingElement.GetAttribute( "rightMargin" );
				if( rightMargin.Length > 0 )
				{
					view.RightMargin = ConvertUtil.parseDoubleWithLocalDecimalSeparator( rightMargin ) * 10;
				}
			}
		}

		private static void parseRuleButtonList( Manifest manifest, View view, XmlElement viewElement )
		{
			string xsfPrefix = manifest.XsfPrefix;
			string buttonFilter = NamespaceUtil.toFullName( xsfPrefix, "unboundControls" ) + "/" + NamespaceUtil.toFullName( xsfPrefix, "button" );
			XmlNodeList buttonElementList = DOMUtil.selectNodes( viewElement, buttonFilter, 0, manifest.NsResolver );
			ArrayList buttonList = new ArrayList();
			foreach( XmlElement buttonElement in buttonElementList ){
				RuleButton ruleButton = new RuleButton();
				string name = buttonElement.GetAttribute( "name" );
				if( name.Length <= 0 ){
					throw new InfoJetException( "Cannot find button name", "XMP31" );
				}
				ruleButton.ButtonName = name;
				XmlElement ruleSetActionElement = DOMUtil.findChildElementByLocalName( buttonElement, "ruleSetAction" );
				if( ruleSetActionElement == null ){
					continue;
				}
				string ruleSetName = ruleSetActionElement.GetAttribute( "ruleSet" );
				if( ruleSetName.Length <= 0 ){
					throw new InfoJetException( "Cannot find ruleSetAction ruleSet", "XMP32" );
				}
				ruleButton.RuleSetName = ruleSetName;
				buttonList.Add( ruleButton );
			}
			view.RuleButtonList = buttonList;
		}

		private static void parseViewWidth(Manifest manifest, View view)
		{
			XmlElement root = manifest.Doc.DocumentElement;
			string xsfPrefix = manifest.XsfPrefix;
			
			StringBuilder viewWidthFilterBuffer = new StringBuilder();
			//CID 0990 //2011.07.19 //Begin
            viewWidthFilterBuffer.Append("/");
            viewWidthFilterBuffer.Append(NamespaceUtil.toFullName(xsfPrefix, "xDocumentClass"));
            viewWidthFilterBuffer.Append("/");
            viewWidthFilterBuffer.Append(NamespaceUtil.toFullName(xsfPrefix, "package"));
            viewWidthFilterBuffer.Append("/");
            viewWidthFilterBuffer.Append(NamespaceUtil.toFullName(xsfPrefix, "files"));
            viewWidthFilterBuffer.Append("/");
            //CID 0990 //2011.07.19 //End
            viewWidthFilterBuffer.Append(NamespaceUtil.toFullName(xsfPrefix, "file"));
			viewWidthFilterBuffer.Append("[@name='");
			viewWidthFilterBuffer.Append(view.Transform);
			viewWidthFilterBuffer.Append("']/");
			viewWidthFilterBuffer.Append(NamespaceUtil.toFullName(xsfPrefix, "fileProperties"));
			viewWidthFilterBuffer.Append("/");
			viewWidthFilterBuffer.Append(NamespaceUtil.toFullName(xsfPrefix, "property"));
			viewWidthFilterBuffer.Append("[@name='viewWidth']");
            XmlElement viewWidthElement = (XmlElement) DOMUtil.selectANode(root, viewWidthFilterBuffer.ToString(), manifest.NsResolver);
            if (viewWidthElement == null)
			{
				//CID 0425 //2009.10.16 //Comment
				//view.ViewWidth = "542px"; //InfoPath 2003
				//CID 0425 //2009.10.16 //End
				//理论上说最好不设置宽度，但是如果不设置DatePicker的Button将不正常。
				//view.ViewWidth = "629px"; //InfoPath 2007
				//还是保持不变，因为实际上如果有一个表格存在，ViewWidth将不起作用。
				//CID 0425 //2009.10.16 //Begin
				string defaultViewWidth = ConfigUtil.DefaultViewWidth();
				if( defaultViewWidth != null && defaultViewWidth.Length > 0 )
				{
					view.ViewWidth = defaultViewWidth;
				}
				//CID 0425 //2009.10.16 //End
			}
			else
			{
				view.ViewWidth = viewWidthElement.GetAttribute("value");
			}
		}
		
		public static void parseErrorCondition(Manifest manifest)
		{
			XmlElement root = manifest.Doc.DocumentElement;
			string xsfPrefix = manifest.XsfPrefix;
			
			ArrayList errorConditionList = new ArrayList();

			string errorConditionFilter = "//" + NamespaceUtil.toFullName(xsfPrefix, "errorCondition");
			XmlNodeList errorCondElementList = DOMUtil.selectNodes(root, errorConditionFilter, 0, manifest.NsResolver);
			for( int i = 0; i < errorCondElementList.Count; i ++ ) 
			{
				XmlElement errorCondElement = (XmlElement) errorCondElementList[ i ];
				ErrorCondition errorCondition = new ErrorCondition();
				errorCondition.Id = i + "";
				errorCondition.Match = errorCondElement.GetAttribute("match");
				errorCondition.ExpressionContext = errorCondElement.GetAttribute("expressionContext");
				if (errorCondition.ExpressionContext.Length <= 0)
				{
					errorCondition.ExpressionContext = ".";
				}
				errorCondition.Expression = errorCondElement.GetAttribute("expression");
				errorCondition.ShowErrorOn = errorCondElement.GetAttribute("showErrorOn");
				if (errorCondition.ShowErrorOn.Length <= 0)
				{
					errorCondition.ShowErrorOn = ".";
				}
				string errorMessageFilter = NamespaceUtil.toFullName(xsfPrefix, "errorMessage");
				XmlElement errorMessageElement = (XmlElement) DOMUtil.selectOneNode(errorCondElement, errorMessageFilter, manifest.NsResolver);
				errorCondition.Type = errorMessageElement.GetAttribute("type");
				if (errorCondition.Type.Length <= 0)
				{
					errorCondition.Type = "modeless";
				}
				errorCondition.ShortMessage = errorMessageElement.GetAttribute("shortMessage");
				// or InnerXML.
				errorCondition.ErrorMessage = errorMessageElement.InnerText;
				string modalMessage = errorCondition.ErrorMessage;
				if (modalMessage != null)
				{
					errorCondition.ErrorMessage = modalMessage;
				}

				errorConditionList.Add(errorCondition);
			}
			manifest.ErrorConditionList = errorConditionList;
		}

        //CID 0858 //2011.03.29 //Begin
        public static void parseErrorBlank(Manifest manifest)
        {
            XmlElement root = manifest.Doc.DocumentElement;
            string xsf3Prefix = manifest.Xsf3Prefix;

            ArrayList errorblankList = new ArrayList();

            string errorBlankFilter = "//" + NamespaceUtil.toFullName(xsf3Prefix, "errorBlank");
            XmlNodeList errorBlanklementList = DOMUtil.selectNodes(root, errorBlankFilter, 0, manifest.NsResolver);
            foreach (XmlElement errorBlankElement in errorBlanklementList)
            {
                ErrorBlank errorBlank = new ErrorBlank();
                errorBlank.Match = errorBlankElement.GetAttribute("match");
                errorBlank.ExpressionContext = errorBlankElement.GetAttribute("expressionContext");
                errorBlank.Expression = errorBlankElement.GetAttribute("expression");
                bool isRichTextBox = false;
                foreach (XmlToEdit xmlToEdit in manifest.XmlToEditList)
                {
                    if (xmlToEdit.Component.Equals(JetConstant.CMP_xField) &&
                        xmlToEdit.Type.Equals("rich") &&
                        xmlToEdit.Item.Equals(errorBlank.Match))
                    {
                        isRichTextBox = true;
                        break;
                    }
                }
                //CID 1208 //2012.05.27 //!
                if (isRichTextBox)
                {
                    errorblankList.Add(errorBlank);
                }
            }
            manifest.ErrorBlankList = errorblankList;
        }
        //CID 0858 //2011.04.13 //End

		public static void parseQuery( HttpContext context, Manifest manifest ){
			XmlElement root = manifest.Doc.DocumentElement;
			string xsfPrefix = manifest.XsfPrefix;

			string queryFilter = NamespaceUtil.toFullName(xsfPrefix, "query");
			XmlElement queryElement = (XmlElement)DOMUtil.selectANode( root, queryFilter, manifest.NsResolver );
			if( queryElement != null ){
				Query query = new Query();
				Object dataAdapter = XSNManifestDataAdapterParseWorker.parseDataAdapterInContainer( context, manifest, queryElement );
				if( dataAdapter is DataADOAdapter ){
					query.AdoAdapter = (DataADOAdapter)dataAdapter;
				}
				if( dataAdapter is DataWSAdapter ){
					query.WSAdapter = (DataWSAdapter)dataAdapter;
				}
				if( dataAdapter is DataFileAdapter ){
					query.FileAdapter = (DataFileAdapter) dataAdapter;
				}
				if( dataAdapter is DataSPListAdapter ){
					query.SPListAdapter = (DataSPListAdapter) dataAdapter;
				}

				manifest.Query= query;
			}
		}

		public static void parseOnLoad( Manifest manifest ){
			XmlElement root = manifest.Doc.DocumentElement;
			string xsfPrefix = manifest.XsfPrefix;

			string onLoadFilter = NamespaceUtil.toFullName(xsfPrefix, "onLoad");
			XmlElement onLoadElement = (XmlElement)DOMUtil.selectANode( root, onLoadFilter, manifest.NsResolver );
			if( onLoadElement != null ){
				OnLoad onLoad = new OnLoad();
				onLoad.RuleSetList = new ArrayList();
				string ruleSetActionFilter = NamespaceUtil.toFullName(xsfPrefix, "ruleSetAction");
				XmlNodeList ruleSetActionElementList = DOMUtil.selectNodes( onLoadElement, ruleSetActionFilter, 0, manifest.NsResolver );
				foreach( XmlElement ruleSetActionElement in ruleSetActionElementList ){
					string ruleSetName = ruleSetActionElement.GetAttribute( "ruleSet" );
					if( ruleSetName.Length <= 0 ){
						throw new InfoJetException("No ruleSetAction - ruleSet Attribute.", "XMP09");
					}
					RuleSet ruleSet = XSNManifestRuleSetParseWorker.parseRuleSetByName( manifest, ruleSetName );
					//CID 0235 //2009.03.03 //Begin
                    //CID 0735 //2010.12.19 //Begin
					ruleSet = InfoJetSoft.Service.EscapeRule.RuleSetFilter.Filter( manifest, null, null, ruleSet );
                    //CID 0735 //2010.12.19 //End
					//CID 0235 //2009.03.03 //End
					if( ruleSet != null )
					{
						onLoad.RuleSetList.Add( ruleSet );
					}
				}
				manifest.OnLoad = onLoad;
			}
		}

		public static void parseImportParameters( Manifest manifest )
		{
			XmlElement root = manifest.Doc.DocumentElement;
			string xsfPrefix = manifest.XsfPrefix;

			string importParamsFilter = NamespaceUtil.toFullName(xsfPrefix, "importParameters");
			XmlElement importParamsElement = (XmlElement)DOMUtil.selectANode( root, importParamsFilter, manifest.NsResolver );
			
			ImportParameters importParams = new ImportParameters();
			
			if( importParamsElement != null )
			{
				string enabled = importParamsElement.GetAttribute( "enabled" );
				if( enabled != null && enabled.Equals( JetConstant.YES ) )
				{
					importParams.Enabled = true;
				}
				string useScriptHandler = importParamsElement.GetAttribute( "useScriptHandler" );
				if( useScriptHandler != null && useScriptHandler.Equals( JetConstant.YES ) )
				{
					importParams.UseScriptHandler = true;
				}

				//CID 0237 //2009.03.02 //Begin
				string importSourceFilter = NamespaceUtil.toFullName(xsfPrefix, "importSource");
				XmlElement importSourceElement = (XmlElement)DOMUtil.selectANode( importParamsElement, importSourceFilter, manifest.NsResolver );
				if( importSourceElement != null )
				{
					ImportSource importSource = new ImportSource();
					importSource.Name = importSourceElement.GetAttribute("name");
					importSource.Schema = importSourceElement.GetAttribute("schema");
					importSource.Transform = importSourceElement.GetAttribute("transform");
					importSource.AuthoringOfTransform = importSourceElement.GetAttribute("authoringOfTransform");

					CABFile cabFile = CABFileFinder.findCABFile( manifest, importSource.Transform );
					XmlDocument xslDoc = DOMUtil.buildDoc( cabFile.ByteOutput );
					importSource.ActionList = parseImportActions( xslDoc );

					importParams.ImportSource = importSource;
				}
				//CID 0237 //2009.03.02 //End
			}

			manifest.ImportParameters = importParams;
		}

		//CID 0237 //2009.03.02 //Begin
		public static ArrayList parseImportActions( XmlDocument xslDoc )
		{
			ArrayList actionList = new ArrayList();
			NamespaceResolver nsResolver = new NamespaceResolver( xslDoc );
			XmlElement actionTableElement = DOMUtil.selectOneNode( xslDoc, "/xsl:stylesheet/xsl:template/xdActionTable:actionTable", nsResolver ) as XmlElement;
			string sourceRoot = actionTableElement.GetAttribute( "sourceRoot" );

			XmlNodeList actionElementList = DOMUtil.selectNodes( actionTableElement, "xdActionTable:actions/xdActionTable:action[@enabled='1']", 0, nsResolver );
			foreach( XmlElement actionElement in actionElementList )
			{
				ImportAction importAction = new ImportAction();
				importAction.actionType = actionElement.GetAttribute( "type" );

				XmlElement sourceElement = DOMUtil.selectOneNode( actionElement, "xdActionTable:source", nsResolver ) as XmlElement;
				importAction.source = new ImportActionSource();
				importAction.source.root = sourceRoot;
				importAction.source.relativeXPath = sourceElement.GetAttribute( "relativeXPath" );
				importAction.source.parentRelativeXPath = sourceElement.GetAttribute( "parentRelativeXPath" );
				importAction.source.qName = sourceElement.GetAttribute( "QName" );
				importAction.source.fullXPath = importAction.source.root + "/" + importAction.source.relativeXPath;
				
				XmlElement insertElement = DOMUtil.selectANode( actionElement, "xdActionTable:insert", nsResolver ) as XmlElement;
				if( insertElement != null )
				{
					importAction.insert = new ImportActionInsert();
					XmlElement orderElement = DOMUtil.selectANode( insertElement, "xdActionTable:order", nsResolver ) as XmlElement;
					if( orderElement != null )
					{
						importAction.insert.order = orderElement.InnerText;
					}
					XmlElement removeBlanksElement = DOMUtil.selectANode( insertElement, "xdActionTable:removeBlanks", nsResolver ) as XmlElement;
					if( removeBlanksElement != null )
					{
						importAction.insert.removeBlanks = removeBlanksElement.InnerText;
					}
					XmlElement matchElement = DOMUtil.selectANode( insertElement, "xdActionTable:match", nsResolver ) as XmlElement;
					if( matchElement != null )
					{
						importAction.insert.match = matchElement.InnerText;
						importAction.insert.matchType = matchElement.GetAttribute("type");
					}
					//CID 0238 //2009.03.08 //Begin
					XmlElement prefixElement = DOMUtil.selectANode( insertElement, "xdActionTable:prefix", nsResolver ) as XmlElement;
					if( prefixElement != null )
					{
						importAction.insert.prefix = prefixElement.InnerText;
						importAction.insert.prefixType = prefixElement.GetAttribute("type");
					}
					//CID 0238 //2009.03.08 //End
				}

				//CID 0238 //2009.03.08 //Begin
				XmlElement skipElement = DOMUtil.selectANode( actionElement, "xdActionTable:skip", nsResolver ) as XmlElement;
				importAction.skip = (skipElement !=  null);
				//CID 0238 //2009.03.08 //End

				//CID 0238 //2009.03.08 //Begin
				XmlElement concatenateElement = DOMUtil.selectANode( actionElement, "xdActionTable:concatenate", nsResolver ) as XmlElement;
				if( concatenateElement != null )
				{
					importAction.concatenate = new ImportActionConcatenate();
					importAction.concatenate.isAttribute = false;
					importAction.concatenate.xhtml = concatenateElement.GetAttribute( "xhtml" );
					XmlElement ignoreBlankFieldsElement = DOMUtil.selectANode( concatenateElement, "xdActionTable:ignoreBlankFields", nsResolver ) as XmlElement;
					if( ignoreBlankFieldsElement != null )
					{
						importAction.concatenate.ignoreBlankFields = ignoreBlankFieldsElement.InnerText;
					}
					XmlElement separatorElement = DOMUtil.selectANode( concatenateElement, "xdActionTable:separator", nsResolver ) as XmlElement;
					if( separatorElement != null )
					{
						importAction.concatenate.separatorType = separatorElement.GetAttribute( "type" );
						importAction.concatenate.separator = separatorElement.InnerText;
					}
					XmlElement prefixElement = DOMUtil.selectANode( concatenateElement, "xdActionTable:prefix", nsResolver ) as XmlElement;
					if( prefixElement != null )
					{
						importAction.concatenate.prefixType = prefixElement.GetAttribute( "type" );
						importAction.concatenate.prefix = prefixElement.InnerText;
					}
				}
				//CID 0238 //2009.03.08 //End

				//CID 0243 //2009.03.14 //Begin
				XmlElement keepAttributeElement = DOMUtil.selectANode( actionElement, "xdActionTable:keepAttribute", nsResolver ) as XmlElement;
				importAction.keepAttribute = (keepAttributeElement !=  null);
				//CID 0243 //2009.03.14 //End

				//CID 0243 //2009.03.14 //Begin
				XmlElement concatenateAttibuteElement = DOMUtil.selectANode( actionElement, "xdActionTable:concatenateAttribute", nsResolver ) as XmlElement;
				if( concatenateAttibuteElement != null )
				{
					importAction.concatenate = new ImportActionConcatenate();
					importAction.concatenate.isAttribute = true;
					importAction.concatenate.xhtml = concatenateAttibuteElement.GetAttribute( "xhtml" );
					XmlElement ignoreBlankFieldsElement = DOMUtil.selectANode( concatenateAttibuteElement, "xdActionTable:ignoreBlankFields", nsResolver ) as XmlElement;
					if( ignoreBlankFieldsElement != null )
					{
						importAction.concatenate.ignoreBlankFields = ignoreBlankFieldsElement.InnerText;
					}
					XmlElement separatorElement = DOMUtil.selectANode( concatenateAttibuteElement, "xdActionTable:separator", nsResolver ) as XmlElement;
					if( separatorElement != null )
					{
						importAction.concatenate.separatorType = separatorElement.GetAttribute( "type" );
						importAction.concatenate.separator = separatorElement.InnerText;
					}
					XmlElement prefixElement = DOMUtil.selectANode( concatenateAttibuteElement, "xdActionTable:prefix", nsResolver ) as XmlElement;
					if( prefixElement != null )
					{
						importAction.concatenate.prefixType = prefixElement.GetAttribute( "type" );
						importAction.concatenate.prefix = prefixElement.InnerText;
					}
				}
				//CID 0243 //2009.03.14 //End

				actionList.Add( importAction );
			}

			return actionList;
		}
		//CID 0237 //2009.03.02 //End

        //CID 0749 //2011.08.30 //Begin
        public static void parseSignedDataBlocks(Manifest manifest)
        {
            if (ConfigUtil.EnableDigitalSignature())
            {
                XmlElement root = manifest.Doc.DocumentElement;
                string[] steps = new string[] { "documentSignatures", "signedDataBlock" };
                List<XmlElement> blockElementList = QuickSelectUtil.SelectChildElementsByLocalNameSteps(root, steps);
                foreach (XmlElement blockElement in blockElementList)
                {
                    if (manifest.SignedDataBlockList == null)
                    {
                        manifest.SignedDataBlockList = new ArrayList();
                    }
                    SignedDataBlock block = new SignedDataBlock();
                    block.Name = blockElement.GetAttribute("name");
                    block.Data = blockElement.GetAttribute("data");
                    block.Location = blockElement.GetAttribute("signatureLocation");
                    block.Mode = blockElement.GetAttribute("mode");
                    XmlElement messageElement = QuickSelectUtil.SelectChildElementByLocalName(blockElement, "message");
                    if (messageElement != null)
                    {
                        block.Message = messageElement.InnerText;
                    }
                    manifest.SignedDataBlockList.Add(block);
                }
            }
        }
        //CID 0749 //2011.08.30 //End
	}
}